﻿#region << 版 本 注 释 >>
/*----------------------------------------------------------------
// Copyright (C) 2021 kingerrobot
// 版权所有。 
//
// 文件名：BeforeWarehousingImpl
// 文件功能描述：硫化排虚拟扫描
//
// 创建者：名字 (zzl)
// 时间：2021/12/6 15:01:56
//
// 修改人：
// 时间：
// 修改说明：
// 版本：V1.0.0
//----------------------------------------------------------------*/
#endregion


namespace KingerRobot.MexicoSailunMDC.SpiService;

[Logging]
public class RotateScanVirtualImpl : IRotateScanVirtualService
{
    private readonly static ITask _Task = new BTask();
    private readonly static ITaskCmd _TaskCmd = new BTaskCmd();
    private readonly static IWcsNetInCuring _WcsNetInCuring = new BWcsNetInCuring();
    private readonly static IWmsOutOrderSummary _WmsOutOrderSummary = new BWmsOutOrderSummary();
    private readonly static IBakTask _BakTask = new BBakTask();
    private readonly static IWms2MesService _Wms2MesService = new Wms2MesImpl();

    public long UpdateTaskScanLoc(long locId, int lineTaskNo)
    {
        return _Task.UpdateSpinScanId(locId, lineTaskNo);
    }
    public long CreateTask(long locId, string productCode, int lineTaskNo)
    {
        if (locId == 0)
        {
            return -1;
        }
        // 获取线体任务开始位置已经是当前位置
        var lineTaskCmd = _TaskCmd.GetTaskCmdByTaskNo(lineTaskNo);
        if (lineTaskCmd is not null && locId == lineTaskCmd.StartLoc)
        {
            return 1;
        }
        var lineTask = _Task.GetTaskByTaskNo(lineTaskNo);
        var skuId = lineTask?.SkuId ?? 0;
        var summaryId = lineTask?.SummaryId ?? 0;
        var lineTaskId = lineTask?.Id ?? 0;

        // 获取虚拟扫描位可送达硫化排取胎位
        var wcsNetInCuring = _WcsNetInCuring.GetWcsNetinCuringByScanLoc(locId);
        var tranLoc = wcsNetInCuring?.TranLoc ?? 0;
        if (tranLoc == 0)
        {
            return -2;
        }

        // 获取指令
        var taskCmd = _TaskCmd.GetTaskCmdByProductCode(productCode);
        if (taskCmd is null)
        {
            if (lineTask is null)
            {
                var bakWcsTask = _BakTask.GetBakTaskByProductCode(productCode);
                skuId = bakWcsTask?.SkuId ?? 0;
            }

            // 这里应该生成异常任务
            var taskAbnormalId = UpdateAbnormalTaskAndCmd(locId,
                skuId,
                tranLoc,
                0,
                $"线体任务:{lineTaskNo}，条码:{productCode}未找到",
                lineTask,
                lineTaskNo);

            // 重新请料
            _WmsOutOrderSummary.UpdateOutOrderSumaryRealNum(summaryId);

            // 异常同步MES
            if (taskAbnormalId > 0)
            {
                SyncMes(productCode, locId, tranLoc);
            }

            return taskAbnormalId;
        }


        // 无法送达
        var targetLoc = taskCmd.TargetLoc;
        var taskCmdId = taskCmd.Id.GetValueOrDefault();
        if (targetLoc != tranLoc)
        {
            var taskNo = taskCmd.TaskNo.GetValueOrDefault();
            var ptask = _Task.GetTaskByTaskNo(taskNo);
            skuId = ptask?.SkuId ?? 0;
            if (taskNo != lineTaskNo)
            {
                // 删除线体任务
                _Task.BakAndDeleteTaskAndCmd(lineTaskId);
            }

            // 这里应该生成异常任务
            var taskAbnormalId = UpdateAbnormalTaskAndCmd(locId,
                skuId,
                tranLoc,
                0,
                $"线体任务:{lineTaskNo} 条码：{productCode} 开始位置{locId}无法送达{targetLoc}",
                ptask,
                lineTaskNo);

            // 重新请料
            _WmsOutOrderSummary.UpdateOutOrderSumaryRealNum(summaryId);

            // 异常同步MES
            if (taskAbnormalId > 0)
            {
                SyncMes(productCode, locId, tranLoc);
            }

            return taskAbnormalId;
        }

        // 修改开始位置
        _TaskCmd.UpdateCmdStartLoc(taskCmdId, locId);

        return 1;
    }

    public long UpdateAbnormalTaskAndCmd(long locId, long skuId, long targetLoc, decimal angle, string remark, POWcsTask task, int taskNo)
    {
        if (task is null)
        {
            WriteLog($"任务不存在：{taskNo}, 重新创建任务。");
            return CreateAbnormalTaskAndCmd(locId, skuId, targetLoc, angle, $"任务已创建或者不存在,{remark}", task, taskNo);
        }


        var taskId = task.Id.GetValueOrDefault();
        _Task.UpdateTask(taskId, new POWcsTask
        {
            TaskType = (int)EnumTaskType.Abnormal,
            TaskNo = taskNo,
            LineTaskNo = task.TaskNo,
            RemarkMemo = remark,
        });

        _TaskCmd.BakAndDeleteCmd(taskId);

        var cmd = _TaskCmd.CreateTaskCmd(new()
        {
            TaskId = taskId,
            TaskNo = taskNo,
            TaskType = (int)EnumTaskType.Abnormal,
            StartLoc = locId,
            CurrentLoc = locId,
            TargetLoc = targetLoc,
            CmdStatus = (int)EnumTaskCmdStatus.Executable,
            CmdType = (int)EnumTaskType.Abnormal,
            SpinAngle = angle,

        });

        return taskId;

    }

    /// <summary>
    /// 创建异常任务和指令
    /// </summary>
    /// <param name="locId"></param>
    /// <param name="skuId"></param>
    /// <param name="targetLoc"></param>
    /// <param name="angle"></param>
    /// <param name="remark"></param>
    /// <returns></returns>
    public long CreateAbnormalTaskAndCmd(long locId, long skuId, long targetLoc, decimal angle, string remark, POWcsTask task, int taskNo)
    {
        var taskId = _Task.CreateOutAbnormalTask(locId, skuId, remark, task, taskNo);
        var taskAbnormal = _Task.GetExecutedTaskByTaskId(taskId);
        var cmd = _TaskCmd.CreateTaskCmd(new()
        {
            TaskId = taskAbnormal?.Id,
            TaskNo = taskAbnormal?.TaskNo,
            TaskType = taskAbnormal?.TaskType,
            StartLoc = locId,
            CurrentLoc = locId,
            TargetLoc = targetLoc,
            CmdStatus = (int)EnumTaskCmdStatus.Executable,
            CmdType = (int)EnumTaskType.Abnormal,
            SpinAngle = angle,

        });

        _Task.BakAndDeleteTaskAndCmd(task?.Id.GetValueOrDefault() ?? 0);

        return taskAbnormal.Id ?? 0;
    }

    /// <summary>
    /// 同步MES
    /// </summary>
    /// <param name="barCode"></param>
    /// <param name="startLoc"></param>
    /// <param name="taskId"></param>
    private void SyncMes(string barCode, long startLoc, long targetLoc)
    {
        // 16.异常输送（WMS->MES）
        _Wms2MesService.PushAbnormal(barCode, startLoc, targetLoc);
    }
}